package com.cjm.algorithm.queue;

import java.util.*;

public class IsValid20 {
    public static void main(String[] args) {
        IsValid20 isValid20 = new IsValid20();
        isValid20.isValid24042120("){");
    }

    public boolean isValid24042120(String s) {
        if (s == null || s.isEmpty()) return false;
        int length = s.length();
        if (length % 2 != 0) return false;

        Stack<Character> xx = new Stack<>();
        List<Character> left = Arrays.asList('{', '[', '(');
        List<Character> right = Arrays.asList('}', ']', ')');
        Map<Character, Character> map = new HashMap<>();
        map.put('}', '{');
        map.put(']', '[');
        map.put(')', '(');

        for (int i = 0; i < length; i++) {
            char c = s.charAt(i);
            if (left.contains(c)) {
                xx.push(c);
                continue;
            }
            if (right.contains(c)) {
                if (xx.empty()) {
                    return false;
                }
                Character peek = xx.pop();
                if (peek == null || map.get(c) != peek) {
                    return false;
                } else {
                    xx.pop();
                }
            }
        }
        return xx.empty();
    }


    private static final List<Character> xx = Arrays.asList(')', '}', ']');
    private static final Map<Character, Character> map = new HashMap<>();

    static {
        map.put(')', '(');
        map.put('}', '{');
        map.put(']', '[');
    }

    public boolean isValid1(String s) {
        Stack<Character> stack = new Stack<>();
        int length = s.length();
        if (length % 2 != 0) {
            return false;
        }
        for (int i = 0; i < length; i++) {
            char right = s.charAt(i);
            if (xx.contains(right)) {
                Character left = null;
                try {
                    left = stack.pop();
                } catch (Exception e) {
                    return false;
                }
                Character ll = map.get(right);
                if (ll != null && ll.equals(left)) {
                    continue;
                }
                return false;
            }
            stack.push(right);
        }
        return stack.isEmpty();
    }

    public boolean isValid(String s) {
        if (s == null || s.isEmpty()) {
            return false;
        }
        int length = s.length();
        if (length % 2 != 0) return false;
        Deque<Character> queue = new ArrayDeque<>(s.length());
        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);
            if (xx.contains(c)) {
                Character poll = queue.pollLast();
                Character c1 = map.get(c);
                if (c1.equals(poll)) {
                    continue;
                }
                return false;
            }
            queue.add(c);
        }
        return queue.isEmpty();
    }
}
